﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Media;
using System.Windows;
using System.Windows.Input;

namespace MuchRectDemo
{
    class VisualHost : FrameworkElement
    {
        private readonly VisualCollection _children;
        private readonly DrawingVisual _drawingVisual;
        private double _scale = 1.0;
        private Point? _highlightedPoint = null;
        private Point? _originalClickPoint = null; // 原始点击位置

        public VisualHost()
        {
            _children = new VisualCollection(this);
            _drawingVisual = new DrawingVisual();
            _children.Add(_drawingVisual);

            this.MouseDown += OnMouseDown;
            this.MouseWheel += OnMouseWheel;
            DrawRectangles();
        }

        private void DrawRectangles()
        {
            using (DrawingContext dc = _drawingVisual.RenderOpen())
            {
                double radius = 300 * _scale; // 圆的半径
                Point center = new Point(radius, radius);
                double rectSize = 5 * _scale; // 矩形的大小
                int count = 200; // 每行/列的矩形数量

                // 设置裁剪区域为圆形
                this.Clip = new EllipseGeometry(center, radius, radius);

                // 绘制统一的背景色
                dc.DrawRectangle(Brushes.LightGray, null, new Rect(0, 0, 2 * radius, 2 * radius));

                for (int i = 0; i < count; i++)
                {
                    for (int j = 0; j < count; j++)
                    {
                        double x = i * rectSize;
                        double y = j * rectSize;
                        Rect rect = new Rect(x, y, rectSize, rectSize);

                        // 检查矩形是否在圆内
                        if (Math.Pow(x + rectSize / 2 - center.X, 2) + Math.Pow(y + rectSize / 2 - center.Y, 2) <= Math.Pow(radius, 2))
                        {
                            dc.DrawRectangle(Brushes.LightBlue, new Pen(Brushes.Black, 0.5), rect);

                            // 仅在点击时绘制高亮的顶点
                            if (_highlightedPoint.HasValue)
                            {
                                HighlightVertex(dc, rect);
                            }
                        }
                    }
                }
            }
        }

        private void HighlightVertex(DrawingContext dc, Rect rect)
        {
            double pointSize = 2 * _scale; // 顶点的大小
            Brush fillBrush = Brushes.Yellow;

            // 检查并高亮显示点击的顶点
            if (IsPointNear(_highlightedPoint.Value, rect.TopLeft, pointSize))
                dc.DrawEllipse(fillBrush, null, rect.TopLeft, pointSize, pointSize);

            if (IsPointNear(_highlightedPoint.Value, rect.TopRight, pointSize))
                dc.DrawEllipse(fillBrush, null, rect.TopRight, pointSize, pointSize);

            if (IsPointNear(_highlightedPoint.Value, rect.BottomLeft, pointSize))
                dc.DrawEllipse(fillBrush, null, rect.BottomLeft, pointSize, pointSize);

            if (IsPointNear(_highlightedPoint.Value, rect.BottomRight, pointSize))
                dc.DrawEllipse(fillBrush, null, rect.BottomRight, pointSize, pointSize);
        }

        private bool IsPointNear(Point p1, Point p2, double threshold)
        {
            return Math.Abs(p1.X - p2.X) < threshold && Math.Abs(p1.Y - p2.Y) < threshold;
        }

        private void OnMouseDown(object sender, MouseButtonEventArgs e)
        {
            Point clickPoint = e.GetPosition(this);
            _originalClickPoint = new Point(clickPoint.X / _scale, clickPoint.Y / _scale); // 保存原始点击位置
            _highlightedPoint = clickPoint;
            DrawRectangles();
        }

        private void OnMouseWheel(object sender, MouseWheelEventArgs e)
        {
            double oldScale = _scale;
            _scale += e.Delta > 0 ? 0.1 : -0.1;
            _scale = Math.Max(0.1, _scale); // 防止缩放比例过小

            // 调整高亮点的位置
            if (_originalClickPoint.HasValue)
            {
                _highlightedPoint = new Point(_originalClickPoint.Value.X * _scale, _originalClickPoint.Value.Y * _scale);
            }

            DrawRectangles();
        }

        protected override int VisualChildrenCount => _children.Count;

        protected override Visual GetVisualChild(int index)
        {
            if (index < 0 || index >= _children.Count)
            {
                throw new ArgumentOutOfRangeException();
            }
            return _children[index];
        }
    }
}

